from django.db import models
from School.models import School
from mptt.models import MPTTModel, TreeForeignKey
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
import uuid


def update_student_count(school_id, count):
    print(f"更新学生人数找通道: {count}")
    channel_layer = get_channel_layer()
    print('开始执行try')
    try:
        async_to_sync(channel_layer.group_send)(
            f'student_count_{school_id}',
            {
                'type': 'update_student_post_count',
                'post_count': count
            }
        )
    except Exception as e:
        print(f"发送消息失败: {e}")


# Create your models here.
# Student: 学号，姓名，性别，出生日期，手机号码，邮箱地址，家庭住址，照片

class Student(models.Model):
    gender_choices = (('男', '男'), ('女', '女'))
    sno = models.CharField(db_column="SNo", primary_key=True, null=False, max_length=200)
    name = models.CharField(db_column="SName", max_length=100, null=True, blank=True)
    st_sno = models.CharField(db_column="St_sno", max_length=100, null=False, blank=True)
    gender = models.CharField(db_column="Gender", max_length=100, choices=gender_choices, null=True, blank=True)
    # birthday = models.DateField(db_column="Birthday", null=True, blank=True)
    mobile = models.CharField(db_column="Mobile", max_length=100, null=True, blank=True)
    address = models.CharField(db_column="Address", max_length=200, null=True, blank=True)
    image = models.CharField(db_column="Image", max_length=200, null=True, blank=True)
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    nickname = models.CharField(db_column="Nickname", max_length=100, null=True, blank=True, unique=True)
    friends = models.ManyToManyField('self', blank=True)
    identity = models.CharField(db_column="Identity", max_length=100, null=True, blank=True, default='学生')

    # contact = models.ForeignKey(Contact, on_delete=models.CASCADE, related_name='students', null=True, blank=True)

    class Meta:
        managed = True
        db_table = "Student"
        verbose_name_plural = "学生"

    def __str__(self):
        return "学号:%s\t姓名:%s\t性别:%s" % (self.sno, self.name, self.gender)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        self.notify_student_count()

    def delete(self, *args, **kwargs):
        print(f'准备删除学生: {self}')
        super().delete(*args, **kwargs)
        print('学生已删除。通知学生人数。')
        self.notify_student_count()

    def notify_student_count(self):
        count = Student.objects.filter(school=self.school).count()
        print(count)
        channel_layer = get_channel_layer()
        async_to_sync(channel_layer.group_send)(
            f'student_count_{self.school.id}',
            {
                'type': 'update_student_count',
                'count': count,
            }
        )

    # class Application(models.Model):
#     STATUS_CHOICES = [
#         ('pending', '待处理'),
#         ('rejected', '拒绝'),
#         ('accepted', '同意'),
#     ]
#
#     stu = models.ForeignKey(Student, to_field='sno', on_delete=models.CASCADE)
#     application_content = models.TextField()
#     application_date = models.DateTimeField(auto_now_add=True)
#     status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending')
#     school = models.ForeignKey(School, on_delete=models.CASCADE)
#
#     class Meta:
#         verbose_name_plural = "申请"
#         db_table = "Application"
#
#     def __str__(self):
#         return f"Application by {self.stu.name} on {self.application_date}: {self.application_content[:50]}..."


class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True)

    class Meta:
        verbose_name_plural = "帖子分类"
        db_table = "Category"

    def __str__(self):
        return self.name


class Contact(models.Model):
    TYPE_CHOICES = [
        ('微信', '微信'),
        ('QQ', 'QQ'),
        ('电话', '电话')
    ]
    type = models.CharField(max_length=10, choices=TYPE_CHOICES)
    number = models.CharField(db_column="Number", max_length=100)

    class Meta:
        verbose_name_plural = "联系方式"
        db_table = "Contact"

    def __str__(self):
        return self.number


class Post(models.Model):
    STATUS_CHOICES = [
        ('正常', '正常'),
        ('违规', '违规'),
    ]

    title = models.CharField(max_length=200)
    content = models.TextField()
    student = models.ForeignKey(Student, on_delete=models.CASCADE, null=True, blank=True, related_name='posts_created')
    school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='posts_in_school')
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    likes = models.IntegerField(default=0)
    avatar = models.CharField(db_column="Avatar", max_length=200, null=True, blank=True)
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE, related_name='posts_contact', null=True, blank=True)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='正常')

    class Meta:
        ordering = ['-created_at']
        db_table = "Post"
        verbose_name_plural = "帖子"

    def __str__(self):
        return f"{self.title} - {self.status}"

    def save(self, *args, **kwargs):
        if not self.pk:  # 如果是新创建的对象
            self.fun_on_create()
        super().save(*args, **kwargs)

    def fun_on_create(self):
        if self.school:
            school_id = self.school.id
            count = self.get_post_count_for_school(school_id) + 1
            print('现在一切正常', count)
            update_student_count(school_id, count)

    @staticmethod
    def get_post_count_for_school(school_id):
        return Post.objects.filter(school__id=school_id).count()


# class Post(models.Model):
#     title = models.CharField(max_length=200)
#     content = models.TextField()
#     student = models.ForeignKey('Student', on_delete=models.CASCADE, null=True, blank=True, related_name='posts_created')
#     school = models.ForeignKey('School', on_delete=models.CASCADE, related_name='posts_in_school')
#     category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
#     created_at = models.DateTimeField(auto_now_add=True)
#     likes = models.IntegerField(default=0)
#     avatar = models.CharField(db_column="Avatar", max_length=200, null=True, blank=True)
#     contact = models.ForeignKey('Contact', on_delete=models.CASCADE, related_name='posts_contact', null=True, blank=True)
#
#     class Meta:
#         ordering = ['-created_at']
#         db_table = "Post"
#         verbose_name_plural = "帖子"
#
#     def __str__(self):
#         return self.title
#
#     def save(self, *args, **kwargs):
#         is_new_post = not self.pk
#         super().save(*args, **kwargs)
#         if is_new_post:
#             school_id = self.school.pk
#             count = get_post_count_for_school(school_id)
#             self.update_student_count(school_id, count)
#
#     def update_student_count(self, school_id, count):
#         channel_layer = get_channel_layer()
#         async_to_sync(channel_layer.group_send)(
#             f'student_count_{school_id}',
#             {
#                 'type': 'update_student_count',
#                 'count': count
#             }
#         )


def get_post_count_for_school(school_id):
    return Post.objects.filter(school_id=school_id).count()


class PostLike(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='like')
    student = models.ForeignKey(Student, on_delete=models.CASCADE, null=True, blank=True,
                                related_name='likes_user')

    class Meta:
        verbose_name_plural = "帖子点赞"
        db_table = "PostLike"


class PostImage(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='images')
    image = models.CharField(db_column="Image", max_length=200, null=True, blank=True)  # 照片

    class Meta:
        verbose_name_plural = "帖子图片"

    def __str__(self):
        return f"帖子{self.post.id}的图片"


class Comment(MPTTModel):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments_on_post')
    text = models.TextField()
    student = models.ForeignKey(Student, on_delete=models.CASCADE, null=True, blank=True,
                                related_name='comments_created')
    school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='comments_in_school')
    created_at = models.DateTimeField(auto_now_add=True)
    likes = models.IntegerField(default=0)
    avatar = models.CharField(db_column="Avatar", max_length=200, null=True, blank=True)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')

    class MPTTMeta:
        order_insertion_by = ['created_at']

    class Meta:
        ordering = ['-created_at']
        verbose_name_plural = "评论"

    def __str__(self):
        return f"Comment by {self.student.name if self.student else 'Anonymous'}: {self.text[:50]}..."


class CommentLike(models.Model):
    comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='comment_likes')
    student = models.ForeignKey(Student, on_delete=models.CASCADE, null=True, blank=True,
                                related_name='likes_created')

    class Meta:
        verbose_name_plural = "评论点赞"
        db_table = "CommentLike"


# 商品模型
class Product(models.Model):
    STATUS_CHOICES = (
        ('在售', '在售'),
        ('售空', '售空'),
        ('已下架', '已下架'),
    )
    CHOICES = (
        ('二手书', '二手书'),
        ('生活', '生活'),
        ('学习', '学习'),
        ('电子', '电子'),
        ('其他', '其他'),
    )
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    seller = models.ForeignKey(Student, on_delete=models.CASCADE)
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    name = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    category = models.CharField(max_length=20, choices=CHOICES)
    stock_quantity = models.PositiveIntegerField()
    # image = models.CharField(db_column="Image", max_length=200, null=True, blank=True)  # 照片
    adress = models.CharField(max_length=200)
    aut = models.CharField(db_column="Aut", max_length=200, null=True, blank=True)
    created_at = models.CharField(max_length=100, null=True, blank=True)
    publisher = models.CharField(db_column="Publisher", max_length=200, null=True, blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='在售')

    class Meta:
        verbose_name_plural = "商品"

    def __str__(self):
        return f"{self.seller.name} 的 {self.name}"


class ProductImage(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='img')
    img = models.CharField(db_column="img", max_length=200, null=True, blank=True)  # 照片

    class Meta:
        verbose_name_plural = "商品图片"

    def __str__(self):
        return f"商品{self.product.id}的图片"


# 购物车模型
class Cart(models.Model):
    student = models.OneToOneField(Student, on_delete=models.CASCADE)
    products = models.ManyToManyField(Product, through='CartItem')

    class Meta:
        verbose_name_plural = "购物车"

    def __str__(self):
        return f"{self.student.name}的购物车"


# 购物车中的商品项模型
class CartItem(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()

    class Meta:
        verbose_name_plural = "购物车明细"

    def __str__(self):
        return self.product.name

from datetime import date
from datetime import datetime, timedelta
# 订单模型
class Order(models.Model):
    STATUS_CHOICES = (
        ('待支付', '待支付'),
        ('已支付', '已支付'),
        ('已发货', '已发货'),
        ('已完成', '已完成'),
        ('取消', '取消'),
    )
    CHOICES = (
        ('快递', '快递'),
        ('自提', '自提'),
    )

    seller = models.ForeignKey('Student', on_delete=models.CASCADE, related_name='seller_orders')
    buyer = models.ForeignKey('Student', on_delete=models.CASCADE, related_name='buyer_orders')
    order_date = models.DateTimeField(auto_now_add=True)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2)
    shipping_method = models.CharField(max_length=20, choices=CHOICES, default='快递')  # 修正字段名为小写
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='已支付')
    payment_info = models.CharField(max_length=200, null=True, blank=True)
    ad_info = models.CharField(max_length=200, null=True, blank=True)
    note = models.TextField(null=True, blank=True)

    class Meta:
        verbose_name_plural = "订单"
        ordering = ['-order_date']

    def __str__(self):
        return f"订单#{self.id}"

    def calculate_total_amount(self):
        return sum(item.price_per_item * item.quantity for item in self.orderitem_set.all())

    def update_stock_quantity(self):
        for item in self.orderitem_set.all():
            product = item.product
            product.stock_quantity -= item.quantity
            product.save()

    def save(self, *args, **kwargs):
        print(f'保存订单，当前订单 ID: {self.pk}')  # 输出当前对象的 ID
        super().save(*args, **kwargs)  # 先保存对象，确保 order_date 被设置
        self.fun_on_create()

    def fun_on_create(self):
        print('现在正常')
        # 仅在订单创建时更新今日成交订单数
        today = date.today()
        if self.order_date and self.order_date.date() == today:  # 确保 order_date 不为 None
            try:
                school_id = self.seller.school.id  # 假设 seller 关联了学校
                count = self.get_today_order_count(school_id,self.buyer) + 1
                print('现在一切正常', count)
                self.update_order_count(school_id, count)
            except Exception as e:
                print(f"更新今日订单数失败: {e}")

    @staticmethod
    def get_today_order_count(school_id, buyer):
        today = datetime.today()
        start_of_day = today.replace(hour=0, minute=0, second=0, microsecond=0)
        end_of_day = today.replace(hour=23, minute=59, second=59, microsecond=999999)

        orders = Order.objects.filter(buyer__school_id=school_id, order_date__gte=start_of_day,
                                      order_date__lt=end_of_day)
        print(buyer, today, orders, school_id)
        print(f"匹配的订单: {orders}")  # 打印所有匹配的订单
        return orders.count()
    @staticmethod
    def update_order_count(school_id, count):
        print('现在一切正常妈妈妈妈妈妈啊妈妈们', count)
        channel_layer = get_channel_layer()
        print(channel_layer)
        try:
            async_to_sync(channel_layer.group_send)(
                f'student_count_{school_id}',
                {
                    'type': 'update_order_count',
                    'or_count': count
                }
            )
        except Exception as e:
            print(f"发送消息到频道失败: {e}")

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()
    price_per_item = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        verbose_name_plural = "订单详情"

    def __str__(self):
        return f"{self.quantity} x {self.product.name} in Order #{self.order.id}"


class ChatMessage(models.Model):
    message = models.TextField()
    sender = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='sent_messages')
    receiver = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='received_messages')
    timestamp = models.DateTimeField(auto_now_add=True)
    img = models.CharField(db_column="Image", max_length=200, null=True, blank=True)  # 照片
    is_read = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "聊天消息"
        ordering = ['timestamp']
        db_table = "ChatMessage"

    def __str__(self):
        return f"{self.sender.name} 对 {self.receiver.name} 的消息"


class Report(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    REPORT_TARGET_CHOICES = (
        ('product', 'Product'),
        ('post', 'Post'),
    )
    STATUS_CHOICES = (
        ('待处理', '待处理'),
        ('拒绝', '拒绝'),
        ('同意', '同意'),
    )
    title = models.CharField(max_length=200)
    user = models.ForeignKey('Student', on_delete=models.CASCADE)
    target_type = models.CharField(max_length=10, choices=REPORT_TARGET_CHOICES)
    target_id = models.CharField(max_length=100)
    reason = models.TextField(null=True, blank=True)
    school = models.CharField(max_length=100)
    reported_at = models.DateTimeField(auto_now_add=True)
    img = models.CharField(db_column="Image", max_length=200, null=True, blank=True)  # 照片
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='待处理')

    def get_target(self):
        if self.target_type == 'product':
            return Product.objects.get(id=self.target_id)
        elif self.target_type == 'post':
            return Post.objects.get(id=self.target_id)

    class Meta:
        verbose_name_plural = "举报"
        db_table = "Report"

    def __str__(self):
        return f"{self.user.name} 进行了举报"


from django.utils import timezone


class Notification(models.Model):
    CHOICES = (
        ('举报', '举报'),
        ('上架成功', '上架成功'),
        ('售出', '售出'),
    )
    type = models.CharField(max_length=100, choices=CHOICES)
    user = models.ForeignKey('Student', on_delete=models.CASCADE)
    content = models.TextField(null=True, blank=True)
    product = models.ForeignKey('Product', on_delete=models.CASCADE, null=True, blank=True)
    created_at = models.DateTimeField(default=timezone.now)
    is_read = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "通知"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.user.name}的通知"


class Application(models.Model):
    STATUS_CHOICES = [
        ('待审核', '待审核'),
        ('已批准', '已批准'),
        ('已拒绝', '已拒绝'),
    ]

    student_name = models.ForeignKey(Student, on_delete=models.CASCADE)
    requested_identity = models.CharField(max_length=100)
    reason = models.TextField()
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='待审核')
    application_date = models.DateTimeField(auto_now_add=True)
    faculty = models.CharField(max_length=100)
    tags = models.JSONField(null=True, blank=True)
    # proofs = models.JSONField(null=True, blank=True)
    reject_reason = models.TextField(null=True, blank=True)

    class Meta:
        verbose_name_plural = "申请"
        ordering = ['-application_date']

    def __str__(self):
        return f"{self.student_name}的申请"


class Proofs(models.Model):
    application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='img')
    url = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)

    class Meta:
        verbose_name_plural = "申请图片"

    def __str__(self):
        return f"申请{self.application.id}的图片"


class SchoolApplication(models.Model):
    STATUS_CHOICES = [
        ('待审核', '待审核'),
        ('已批准', '已批准'),
        ('已拒绝', '已拒绝'),
    ]

    name = models.ForeignKey(Student, on_delete=models.CASCADE)
    school_type = models.CharField(max_length=100)
    mobile = models.CharField(max_length=100)
    address = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='待审核')
    application_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = "申请"
        ordering = ['-application_date']

    def __str__(self):
        return f"{self.name}的申请"
